package org.hawk.gwtppc.webtest.tests.methodsuite;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;

import org.hawk.gwtppc.webtest.common.Asserts;
import org.hawk.gwtppc.webtest.common.Test;
import org.hawk.gwtppc.webtest.tests.mock.GenericClassMock;
import org.hawk.gwtppc.webtest.tests.mock.SubClassMock2;

public class GetGenericParameterTypesTest implements Test {

	public void run() throws Throwable {
		Asserts.assertTrue(Arrays.equals(SubClassMock2.class.getDeclaredMethod("processValue", int.class, Object.class, 
				SubClassMock2.class).getGenericParameterTypes(),  new Class[]{ int.class, Object.class, SubClassMock2.class }));
		
		Method m = GenericClassMock.class.getDeclaredMethod("getSomeValue", Object.class, Object.class, Class.class);
		Type[] params = m.getGenericParameterTypes();
		Asserts.assertEquals(params.length,  3);
		
		Asserts.assertTrue(params[0] instanceof TypeVariable);
		TypeVariable<?> tv = (TypeVariable<?>)params[0];
		Asserts.assertEquals(tv.getName(),  "X3");
		Asserts.assertEquals(tv.getGenericDeclaration(), GenericClassMock.class);
		
		Asserts.assertTrue(params[1] instanceof TypeVariable);
		tv = (TypeVariable<?>)params[1];
		Asserts.assertEquals(tv.getName(),  "X2");
		Asserts.assertEquals(tv.getGenericDeclaration(), GenericClassMock.class);
		
		Asserts.assertTrue(params[2] instanceof ParameterizedType);
		ParameterizedType pt = (ParameterizedType)params[2];
		Asserts.assertEquals(pt.getActualTypeArguments().length, 1);
		Asserts.assertTrue(pt.getActualTypeArguments()[0] instanceof TypeVariable);
		Asserts.assertEquals(tv.getGenericDeclaration(), GenericClassMock.class);
		
		tv = (TypeVariable<?>)pt.getActualTypeArguments()[0];
		Asserts.assertEquals(tv.getName(),  "T");
		Asserts.assertEquals(tv.getGenericDeclaration(), m);
	}

	public String getName() {
		return "getGenericParameterTypes()";
	}

}
